package com.ruoyi.shop.modules.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.shop.common.utils.RedisCacheUtils;
import com.ruoyi.shop.modules.domain.Product;
import com.ruoyi.shop.modules.domain.ProductOperLog;
import com.ruoyi.shop.modules.domain.vo.ProductVo;
import com.ruoyi.shop.modules.mapper.AttachmentMapper;
import com.ruoyi.shop.modules.mapper.ProductCategoryMapper;
import com.ruoyi.shop.modules.mapper.ProductMapper;
import com.ruoyi.shop.modules.mapper.ProductOperLogMapper;
import com.ruoyi.shop.modules.service.IProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.ruoyi.shop.common.constant.Constants.PRODUCT_CATEGORY_RANK;
import static com.ruoyi.shop.common.constant.Constants.PRODUCT_ITEM_PREFIX;

/**
 * 商品信息Service业务层处理
 *
 * @author zjc
 * @date 2024-06-22
 */
@Service
@Slf4j
public class ProductServiceImpl implements IProductService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private AttachmentMapper attachmentMapper;
    @Autowired
    private ProductCategoryMapper productCategoryMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RedisCacheUtils redisCacheUtils;
    @Autowired
    private ProductOperLogMapper productOperLogMapper;

    /**
     * 查询商品信息
     *
     * @param id 商品信息主键
     * @return 商品信息
     */
    @Override
    public Product selectProductById(Long id) {
        return redisCacheUtils.queryWithLogicalExpire(
                "product:", id, Product.class,
                30L, TimeUnit.MINUTES,
                10L, TimeUnit.SECONDS,
                10L, TimeUnit.SECONDS,
                productMapper::selectProductById
        );
//        return productMapper.selectProductById(id);
    }

    /**
     * 查询商品信息列表
     *
     * @param product 商品信息
     * @return 商品信息
     */
    @Override
    public List<ProductVo> selectProductList(Product product) {
        List<Product> products = productMapper.selectProductList(product);
        List<ProductVo> productVos = products.stream().map(p -> {
            ProductVo productVo = new ProductVo();
            BeanUtil.copyProperties(p, productVo);
            return productVo;
        }).collect(Collectors.toList());
        return productVos;
    }

    /**
     * 新增商品信息
     *
     * @param product 商品信息
     * @return 结果
     */
    @Override
    public int insertProduct(Product product) {
        return productMapper.insertProduct(product);
    }

    /**
     * 修改商品信息
     *
     * @param product 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateProduct(Product product) {
        // 为了双写一致性，删除缓存
        redisCache.deleteObject(PRODUCT_ITEM_PREFIX + product.getId());
        int updateProduct = productMapper.updateProduct(product);
        return updateProduct;
    }

    /**
     * 批量删除商品信息
     *
     * @param ids 需要删除的商品信息主键
     * @return 结果
     */
    @Override
    public int deleteProductByIds(Long[] ids) {
        return productMapper.deleteProductByIds(ids);
    }

    /**
     * 删除商品信息信息
     *
     * @param id 商品信息主键
     * @return 结果
     */
    @Override
    public int deleteProductById(Long id) {
        return productMapper.deleteProductById(id);
    }

    @Override
    public List<ProductVo> selectProductVoList(int pageNum, int pageSize) {
        // 开启分页查询
        //计算出Limit的始末位置
        int from = (pageNum - 1) * pageSize;
        int to = pageNum * pageSize;
        List<Product> products = productMapper.selectProductPage(from, to);
//        products.forEach(a -> log.info("product:{}", a));

        if (products.isEmpty()) {
            return Collections.emptyList();
        }
        //转Vo
        return products.stream().map(p -> {
            ProductVo productVo = new ProductVo();
            BeanUtil.copyProperties(p, productVo);
            return productVo;
        }).collect(Collectors.toList());
//        List<String> attachmentIds = products.stream().map(Product::getPic).collect(toList());
//        List<Long> categoryIds = products.stream().map(Product::getProductCategoryId).collect(Collectors.toList());
//        List<Long> brandIds = products.stream().map(Product::getProductBrandId).collect(Collectors.toList());
//
//        // 使用CompletableFuture并行查询
//        Map<String, Attachment> attachmentMap = null;
//        Map<Long, Product> brandMap = null;
//        Map<Long, Product> categoryMap = null;
//        CompletableFuture<Map<String, Attachment>> attachmentFuture = CompletableFuture.supplyAsync(() ->
//                attachmentMapper.selectBatchIds(attachmentIds).stream()
//                        .collect(Collectors.toMap(Attachment::getId, Function.identity())));

//        CompletableFuture<Map<Long, Product>> categoryFuture = CompletableFuture.supplyAsync(() ->
//                productMapper.selectProductsByCategoryIds(categoryIds).stream()
//                        .collect(Collectors.toMap(Product::getProductCategoryId, Function.identity())));
//
//        CompletableFuture<Map<Long, Product>> brandFuture = CompletableFuture.supplyAsync(() ->
//                productMapper.selectProductsByBrandIds(brandIds).stream()
//                        .collect(Collectors.toMap(Product::getProductBrandId, Function.identity())));

//        CompletableFuture.allOf(attachmentFuture, categoryFuture, brandFuture).join();
//
//        attachmentMap = attachmentFuture.join();
//        categoryMap = categoryFuture.join();
//        brandMap = brandFuture.join();

//        return products.stream().map(item -> {
//            ProductVo productVo = new ProductVo();
//            BeanUtil.copyProperties(item, productVo);
//
//            Attachment attachment = attachmentMap.get(item.getPic());
//            if (attachment != null) {
//                productVo.setPic(attachment.toString());
//            }
//
//            Product category = categoryMap.get(item.getProductCategoryId());
//            if (category != null) {
//                productVo.setProductCategoryName(category.getName());
//            }
//
//            Product brand = brandMap.get(item.getProductBrandId());
//            if (brand != null) {
//                productVo.setBrandName(brand.getName());
//            }
//            return productVo;
//        }).collect(toList());
    }

    /**
     * 商品分类销量排行榜
     *
     * @return 销量排行榜map
     */
    @Override
    public Map<String, Long> selectProductCategoryRank() {
        //查redis
        Map<String, Long> rank = redisCache.getCacheMap(PRODUCT_CATEGORY_RANK);
        // 如果沒有，先初始化
        if (rank.isEmpty()) {
            initProductCategoryRank();
            // 再查redis
            rank = redisCache.getCacheMap(PRODUCT_CATEGORY_RANK);
        }
        return rank;
    }



    /**
     * 初始化排行榜,存入redis,key为商品分类，value为销量
     */
    public void initProductCategoryRank() {
        //因为涉及累加操作，要先确保删除后在重新建立
        redisCache.deleteObject(PRODUCT_CATEGORY_RANK);

        // 查询商品分类
//        ProductCategory category = new ProductCategory();
//        category.setParentId(0L);
//        List<ProductCategory> categories = productCategoryMapper.selectProductCategoryList(category);
//        if (categories == null) {
//            initProductCategory();
//            categories = redisCache.getCacheList(PRODUCT_CATEGORY_LIST);
//        }
        // 查询商品分类销量
        List<Product> products = productMapper.selectProductList(new Product());
//        products.forEach(a -> log.info("product:{}", a));
        if (products.isEmpty()) {
            return;
        }
        Map<String, Long> categoryCountMap = new HashMap<>();
        for (Product product : products) {
            String categoryName = product.getProductCategoryName();
            Long sale = product.getSale();
            //判断是否存在
            if (categoryCountMap.containsKey(categoryName)) {
                //存在，则累加
                sale += categoryCountMap.get(categoryName);
            }
            categoryCountMap.put(categoryName, sale);
        }
        redisCache.setCacheMap(PRODUCT_CATEGORY_RANK, categoryCountMap);
        log.info("商品分类销量排行榜初始化完成");
    }

    @Override
    public List<ProductVo> selectProductListByIds(List<Long> ids) {
        Long[] idArray = ids.toArray(new Long[ids.size()]);
        //查询商品
        List<Product> products = productMapper.selectProductByIds(idArray);
        if (products.isEmpty()) {
            return null;
        }
        List<ProductVo> productVos = new ArrayList<>();
        for (Product product : products) {

            ProductVo productVo = new ProductVo();
            BeanUtil.copyProperties(product, productVo);
            productVos.add(productVo);
        }
        return productVos;
    }
//    /**
//     * 初始化分类表
//     */
//    public void initProductCategory() {
//        ProductCategory category = new ProductCategory();
//        category.setParentId(1L);
//        // 查询商品分类
//        List<ProductCategory> productCategories = productCategoryMapper.selectProductCategoryList(category);
//
//        if (productCategories.isEmpty()) {
//            log.warn("MySQL商品分类表没有数据，请先导入商品分类");
//            return;
//        }
//        // 写入redis
//        redisCache.setCacheList(PRODUCT_CATEGORY_LIST, productCategories);
//        log.info("商品分类初始化完成");
//    }

    @Override
    public List<ProductVo> selectProductVoRand(int num) {
        List<Product> products = productMapper.selectProductRand(num);
//        products.forEach(a -> log.info("product:{}", a));
        List<ProductVo> productVos = new ArrayList<>();
        for (Product product : products) {
            ProductVo productVo = new ProductVo();
            BeanUtil.copyProperties(product, productVo);
            productVos.add(productVo);
        }
        return productVos;
    }

    @Override
    public int updateStock(Long count, Long id) {
        return productMapper.updateStock(count,id);
    }

    @Override
    public int insertProductHistory(Long productId, Long userId, Integer type) {
        ProductOperLog productOperLog = new ProductOperLog();
        productOperLog.setProductId(productId);
        productOperLog.setUserId(userId);
        productOperLog.setLogType(type);
        return productOperLogMapper.insertProductOperLog(productOperLog);
    }

    @Override
    public int updateKeywordsById(Long productId, String newKeywords) {
        Product product = productMapper.selectProductById(productId);
        if (product == null) {
            return 0; // 产品不存在，直接返回0
        }

        String existingKeywords = product.getKeywords();
        String updatedKeywords;
        if (StringUtils.isNotEmpty(existingKeywords)) {
            // 如果原有关键词非空，则追加新关键词
            updatedKeywords = existingKeywords + "," + newKeywords;
        } else {
            updatedKeywords = newKeywords; // 否则直接使用新关键词
        }

        product.setKeywords(updatedKeywords);
        return productMapper.updateProduct(product);
    }


    @Override
    public List<Long> selectProductOperHistoryByUid(Long userId) {
        List<Long> productIds = productOperLogMapper.selectByUserId(userId);
        if (productIds.isEmpty()) {
            return new ArrayList<>();
        }
        return productIds;
    }
}
